import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { redux } from '@ohif/core';
import { useTranslation } from 'react-i18next';
import { MODIFIER_KEYS } from './config'
import HotkeyField from './HotkeyField';
import validators from './validators';
import { List, Button, Typography, notification } from 'antd';
import cloneDeep from 'lodash.clonedeep';

import './Hotkeys.styl';

const { setHotkeys: hotkeysAction } = redux.actions;

/**
 * Take the updated command and keys and validate the changes with all validators
 *
 * @param {Object} arguments
 * @param {string} arguments.commandName command name string to be updated
 * @param {array} arguments.pressedKeys new array of keys to be added for the commandName
 * @param {array} arguments.hotkeys all hotkeys currently into the app
 * @returns {Object} {errorMessage} errorMessage coming from any of the validator or undefined if none
 */
const validateCommandKey = ({ commandName, pressedKeys, hotkeys, t, onSaveCallback }) => {
  for (const validator of validators) {
    const validation = validator({
      commandName,
      pressedKeys,
      hotkeys,
    });
    if (validation && validation.hasError) {
      notification.error({ message: t(validation.errorMessage), duration: 2 });
      return false;
    }
  }
  return true;
};

function Hotkeys({ hotkeysManager }) {
  const { t } = useTranslation("Preferences");
  const dispatch = useDispatch();

  const { hotkeyDefaults } = hotkeysManager;
  const hotkeyDefinitions = useSelector(state => {
    const { preferences = {} } = state;
    const { hotkeys } = preferences;
    return hotkeys;
  })
  const [hotkeys, setHotkeys] = useState(cloneDeep(hotkeyDefinitions));

  const onReset = () => {
    setHotkeys([ ...hotkeyDefaults ]);
  };

  const onSave = () => {
    hotkeysManager.setHotkeys(hotkeys);
    dispatch(hotkeysAction(hotkeys));
    notification.success({ message: t("Saved Successfully."), duration: 2 });

    if (onSaveCallback) {
      onSaveCallback();
    }
  };

  const onHotkeyChanged = (commandName, keys) => {
    if (validateCommandKey({
      commandName,
      pressedKeys: keys,
      hotkeys,
      t
    })) {
      setHotkeys(prev => {
        const newHotkeys = [...prev];
        newHotkeys.forEach(hk => {
          if (hk.commandName === commandName) {
            hk.keys = keys;
          }
        });
        return newHotkeys;
      });
    }
  };

  return (
    <div className="preference-wrapper">
      <List
        className="hotkeys-list"
        dataSource={hotkeys}
        renderItem={item => {
          const handleChange = keys => {
            const { commandName } = item;
            onHotkeyChanged(commandName, keys);
          };
          return (
            <List.Item>
              <Typography.Text>{t(item.label)}</Typography.Text>
              <HotkeyField
                keys={item.keys}
                modifier_keys={MODIFIER_KEYS}
                handleChange={handleChange}
              ></HotkeyField>
            </List.Item>
          );
        }}
      />
      <div className="hotkeys-btn">
        <Button onClick={onReset}>
          {t("Reset")}
        </Button>
        <Button onClick={onSave}>
          {t("Save")}
        </Button>
      </div>
    </div>
  );
}

export default Hotkeys;
